package com.gjxx.common.utils.old;

import com.google.common.collect.Lists;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zha on 2017/5/27.
 */
public class ConvertUtil {

    private static List<Object> filterArray;

    static {
        filterArray = new ArrayList<>();
        filterArray.add("undefined");
        filterArray.add("null");
        filterArray.add("unknown");
        filterArray.add("NULL");
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。 例如：HELLO_WORLD->helloWorld
     *
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String convertToCamelCase(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线字符串转小写
            return name.toLowerCase();
        }

        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty()) {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return toLowerCaseFirstOne(result.toString());
    }


    /**
     * 首字母转小写
     *
     * @param str
     * @return
     */
    public static String toLowerCaseFirstOne(String str) {
        if (Character.isLowerCase(str.charAt(0))) {
            return str;
        }else {
            return Character.toLowerCase(str.charAt(0)) + str.substring(1);
        }
    }

    /**
     *
     * 遍历key，如果有下划线将转换为驼峰式命名
     * @param data
     * @return
     */
    public static Map<String, Object> convertHumpKey(Map<String, Object> data) {

        if (ObjectUtil.isNull(data))
            return null;

        Map<String, Object> newMap = new HashMap<>();

        for (String key : data.keySet()) {
            String newKey = StringKit.underlineToCamel(key);

            Object value = data.get(key);
            if (ObjectUtil.isNotNull(value) && filterArray.contains(value)) {
                value = "";
            }
            newMap.put(newKey, value);
        }

        data.clear();
        data.putAll(newMap);

        return data;
    }

    /**
     * @param data 传入大写字母key - value 键值对
     * @return 返回小写字母开头的驼峰
     */
    public static Map<String, Object> convertToUpperCaseHumpKey(Map<String, Object> data) {

        if (ObjectUtil.isNull(data)) {
            return null;
        }

        Map<String, Object> newMap = new HashMap<>(16);

        for (String key : data.keySet()) {
            String newKey = convertToCamelCase(key);

            Object value = data.get(key);
            if (ObjectUtil.isNotNull(value) && filterArray.contains(value)) {
                value = "";
            }
            newMap.put(newKey, value);
        }

        data.clear();
        data.putAll(newMap);

        return data;
    }

    /**
     *
     * 遍历key，如果有下划线将转换为驼峰式命名
     * @param data
     * @return
     */
    public static List<Map<String, Object>> convertHumpKey(List<Map<String, Object>> data) {

        if (ObjectUtil.isNull(data))
            return null;

        List<Map<String, Object>> newData = Lists.newArrayList();

        for (Map<String, Object> item : data) {
            newData.add(ConvertUtil.convertHumpKey(item));
        }

        data.clear();
        data.addAll(newData);
        return data;
    }


    /**
     *
     * 遍历key，如果有带下划线的大写字母字符串将转换为驼峰式命名
     * @param data
     * @return
     */
    public static List<Map<String, Object>> convertToUpperCaseHumpKey(List<Map<String, Object>> data) {

        if (ObjectUtil.isNull(data)) {
            return null;
        }

        List<Map<String, Object>> newData = Lists.newArrayList();

        for (Map<String, Object> item : data) {
            newData.add(ConvertUtil.convertToUpperCaseHumpKey(item));
        }

        data.clear();
        data.addAll(newData);
        return data;
    }

    /**
     * 遍历key，如果有下划线将转换为驼峰式命名,并对存在的敏感信息进行AES加密处理
     *
     * @param data
     * @return
     */
    public static List<Map<String, Object>> convertHumpKeyAndEncryptionData(List<Map<String, Object>> data) {

        if (ObjectUtil.isNull(data))
            return null;

        List<Map<String, Object>> newData = Lists.newArrayList();

        // 敏感信息集合
        String[] sensitiveDatas = {"legal_phone", "driver_phone", "license_id", "certificate_no", "passenger_phone", "driver_id",
                "legalPhone", "driverPhone", "licenseId", "certificateNo", "passengerPhone", "driverId"};

        for (Map<String, Object> item : data) {
            for (String sensitiveData : sensitiveDatas) {
                // 验证是否存在敏感信息，若存在，这进行AES加密
                if (item.containsKey(sensitiveData)) {
                    item.put(sensitiveData, AESUtils.aesEncrypt(item.get(sensitiveData).toString()));
                }
            }

            newData.add(ConvertUtil.convertHumpKey(item));
        }

        data.clear();
        data.addAll(newData);
        return data;
    }

    public static <T>T mapToObject(Map<String, Object> map, Class<T> beanClass) throws Exception {
        if (map == null)
            return null;

        Object obj = beanClass.newInstance();

        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){
                continue;
            }

            field.setAccessible(true);
            field.set(obj, map.get(field.getName()));
        }

        return (T)obj;
    }


    public static Map<String, Object> objectToMap(Object obj) {

        if(obj == null){
            return null;
        }

        try {

            Map<String, Object> map = new HashMap<String, Object>();

            Field[] declaredFields = obj.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);

                Object value = field.get(obj);
                if (ObjectUtil.isNotNull(value) && filterArray.contains(value)) {
                    value = "";
                }

                map.put(field.getName(), value);
            }

            return map;

        } catch (IllegalAccessException e) {
            return null;
        }

    }

    public static List<Map<String, Object>> objectToMap(List<?> obj) {

        if(obj == null){
            return null;
        }

        List<Map<String, Object>> result = new ArrayList<>();
        for (Object o : obj) {
            result.add(ConvertUtil.objectToMap(o));
        }
        return result;

    }

    /**
     * 对象转换
     * @param object
     * @param tClass
     * @return
     */
    public static <T>T convertBean(Object object, Class<T> tClass) {

        try {
            Map<String, Object> map = ConvertUtil.objectToMap(object);
            return ConvertUtil.mapToObject(map, tClass);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("转换异常");
        }

    }

    public static <T> T mapToSuperObject(Map<String, Object> map, Class<T> beanClass) throws Exception {
        if (map == null) {
            return null;
        }

        Object obj = beanClass.newInstance();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }

            field.setAccessible(true);
            field.set(obj, map.get(field.getName()));
        }
        Field[] superFields = obj.getClass().getSuperclass().getDeclaredFields();
        for (Field field : superFields) {
            int mod = field.getModifiers();
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }

            field.setAccessible(true);
            field.set(obj, map.get(field.getName()));
        }
        return (T) obj;
    }

    /**
     * JavaBean对象转换为Map  包含父类
     *
     * @param obj 被转换对象
     * @return map（包含父类属性）
     */
    public static Map<String, Object> objectToMapWithSuper(Object obj) {
        Map<String, Object> reMap = new HashMap<>(16);
        if (obj == null) {
            return null;
        }
        try {
            Class<?> objClass = obj.getClass();
            while (objClass != null) {
                Field[] fields = objClass.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    try {
                        Field f = objClass.getDeclaredField(fields[i].getName());
                        f.setAccessible(true);
                        Object o = f.get(obj);
                        reMap.put(fields[i].getName(), o);
                    } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                objClass = objClass.getSuperclass();
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return reMap;
    }

}
